<?php

class IVM {
	private static $instance;
	private $classPaths = array();
	private $classIndexes = array();
	
	private function __construct() {
		$this->classIndexes = $this->loadFile(dirname(__FILE__) . "/_class.php");
	}
	
	/**
	 * Enter description here...
	 *
	 * @return IVM
	 */
	public static function singleton() {
		if (self::$instance == null) {
			self::$instance = new self();
		}
		return self::$instance;
	}
	
	public function addClassPath($classPath) {
		$args = func_get_args();
		foreach ($args as $arg) {
			if (is_array($arg)) {
				$this->classPaths = array_merge($this->classPaths, $arg);
			}
			else {
				$this->classPaths[] = $arg;
			}
		}
		$this->classPaths = array_unique($this->classPaths);
	}
	
	public function findClass($class) {
		//从索引中找
		if (isset($this->classIndexes[$class])) {
			$filename = $this->classIndexes[$class];
			if ($this->isAbsolutePath($filename)) {
				return $filename;
			}
			return realpath(IF_FW_DIR . "/" . $this->classIndexes[$class]);
		}
		
		//从class_path中找
		$class = str_replace(".", DIRECTORY_SEPARATOR, $class);
		foreach ($this->classPaths as $classPath) {
			$file = $classPath . "/" . $class . ".php";
			if (is_file($file)) {
				return realpath($file);
			}
		}
		
		return null;
	}
	
	public function importClass($class) {
		$realClass = self::className($class);
		if (class_exists($realClass, false)) {
			return;
		}
		if (isset($this->classIndexes[$class])) {
			$this->loadFile(realpath(IF_FW_DIR . "/" . $this->classIndexes[$class]), true);
			return;
		}
		foreach ($this->classPaths as $classPath) {
			$array = glob($classPath . DIRECTORY_SEPARATOR . str_replace(".", DIRECTORY_SEPARATOR, $class) . ".php");
			foreach ($array as $path) {
				if (is_file($path)) {
					$this->loadFile($path, true);
				}
			}
		}
	}
	
	public function className($class) {
		if ($class == "") {
			return null;
		}
		$pieces = explode(".", $class);
		return array_pop($pieces);
	}
	
	public function classPackage($class) {
		if ($class == "" || !strstr($class, ".")) {
			return null;
		}
		$pieces = explode(".", $class);
		array_pop($pieces);
		return implode(".", $pieces);
	}
	
	/**
	 * 判断一个名称是否适合作为变量名
	 *
	 * @param string $variableName 变量名
	 * @return boolean
	 */
	public function isValidVariableName($variableName) {
		if (preg_match("/^[_a-z]\\w*$/i", $variableName)) {
			return true;
		}
		return false;
	}
	
	/**
	 * 判断一个类名称（包括包名）是否可用
	 *
	 * @param string $className 类名称（可以含包名，如 a.b.c.ExampleClass）
	 * @return boolean
	 * @since 0.0.3
	 */
	public function isValidClassName($className) {
		if (preg_match("/^([_a-z]\\w*\\.)*([_a-z]\\w*)$/i", $className)) {
			return true;
		}
		return false;
	}
	
	/**
	 * 判断一个路径是否是绝对路径
	 *
	 * @param string $path 路径
	 * @return boolean
	 * @since 0.0.3
	 */
	public function isAbsolutePath($path) {
		$path = trim($path);
		if (preg_match("/^\\//", $path) || preg_match("/^\\\\/", $path) || preg_match("/^\\w:\\\\/", $path)) {
			return true;
		}
		return false;
	}	
	
	/**
	 * 将名称转换为C的编码风格
	 * 
	 * 字母小写，单词之间有中划线<br/>
	 * loadXmlConfig --> load_xml_config
	 *
	 * @param string $name 名称
	 * @return string
	 * @since 0.1
	 */
	public function nameToC($name) {
		$name = preg_replace("/[A-Z]/", "_\\0", $name);
		return strtolower(trim($name, "_"));
	}
	
	/**
	 * 将名称转换为Java的编程风格
	 *
	 * 首字母小写，其余单词的首字母大写<br/>
	 * load_xml_config --> loadXmlConfig
	 * 
	 * @param string $name 名称
	 * @return string
	 * @since 0.1
	 */
	public function nameToJava($name) {
		$name = preg_replace("/_([a-zA-Z])/e", "strtoupper('\\1')", $name);
		return $name;
	}
	
	public function classPaths() {
		return $this->classPaths;
	}
	
	public function addClassIndexes($indexes) {
		if (is_array($indexes)) {
			$this->classIndexes = array_merge($this->classIndexes, $indexes);
		}
	}
	
	public function classIndexes() {
		return $this->classIndexes;
	}
	
	public function loadFile($filename, $once = false) {
		if (!is_file($filename)) {
			return;
		}
		if ($once) {
			return require_once($filename);
		}
		else {
			return require($filename);
		}
	}
}

?>